import store from '@/store'
import request from '@/utils/request'
import { createParser } from 'eventsource-parser'
import { TextDecoder } from 'text-encoding'

export async function sendMessage({ data, onMessage, signal, onError }) {
  const sseParser = createParser(async (event) => {
    if (event.type === 'event') {
      onMessage(event.data)
    }
  })
  // #ifdef MP_WEIXIN
  // eslint-disable-next-line no-undef
  const req = wx.request({
    url: `${import.meta.env.VITE_APP_BASE_API_URL}/api/chat`,
    method: 'POST',
    data,
    enableChunked: true,
    header: {
      Authorization: `Bearer ${store.state.user?.token}`,
    },
    success(res) {
      if (res.statusCode > 299) {
        onError?.(res.data)
      }
    },
  })
  req.onChunkReceived((chunk) => {
    const uint8Array = new Uint8Array(chunk.data)
    const str = new TextDecoder().decode(uint8Array)
    sseParser.feed(str)
  })
  // #endif

  // #ifdef WEB
  // eslint-disable-next-line no-unreachable
  try {
    const resp = await fetch('/api/chat', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${store.state.user?.token}`,
      },
      signal,
    })
    if (resp.status > 299) {
      const errJson = await resp.json()
      onError?.(errJson)
      return
    }
    const reader = resp?.body?.getReader()
    // eslint-disable-next-line no-constant-condition
    while (true) {
      const { done, value } = await reader.read()
      if (done) {
        break
      }
      const str = new TextDecoder().decode(value)
      sseParser.feed(str)
    }
  } catch (_) {
    /* empty */
  }
  // #endif
}

export function getRoomList(data) {
  return request({
    url: '/api/gptRoom',
    data: {
      archive: 0,
      ...data,
    },
  })
}

export function getRoomMsg(data) {
  return request({
    url: '/api/gptMsg',
    data,
  })
}

export function createRoom(version) {
  return request({
    url: '/api/gptRoom',
    method: 'POST',
    data: { version },
  })
}

export function updateRoomDetail(data) {
  return request({
    url: '/api/gptRoom',
    method: 'PUT',
    data,
  })
}

export function deleteRoom(id) {
  return request({
    url: '/api/gptRoom',
    method: 'DELETE',
    data: [id],
  })
}

export function getRoomDetail(id) {
  return request({
    url: `/api/gptRoom/detail/${id}`,
  })
}

export function archiveRoom(id) {
  return request({
    url: '/api/gptRoom',
    method: 'PUT',
    data: { id, archive: 1 },
  })
}

export function unarchiveRoom(id) {
  return request({
    url: '/api/gptRoom',
    method: 'PUT',
    data: { id, archive: 0 },
  })
}

export function transcriptAudio({ file, filePath }) {
  const url =
    import.meta.env.VITE_APP_PLATFORM === 'h5'
      ? '/api/transcriptions'
      : `${import.meta.env.VITE_APP_BASE_API_URL}/api/transcriptions`
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url,
      filePath,
      file,
      name: 'file',
      header: {
        Authorization: `Bearer ${store.state.user?.token}`,
      },
      success: (res) => {
        resolve(res)
      },
      fail: (err) => {
        reject(err)
      },
    })
  })
}

export function uploadFile({ filePath, file }) {
  const url =
    import.meta.env.VITE_APP_PLATFORM === 'h5'
      ? '/api/upload'
      : `${import.meta.env.VITE_APP_BASE_API_URL}/api/upload`
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url,
      filePath,
      file,
      name: 'file',
      formData: {
        roomId: store.state.chat.currentRoomId,
      },
      header: {
        Authorization: `Bearer ${store.state.user?.token}`,
      },
      success: (res) => {
        resolve(res)
      },
      fail: (err) => {
        reject(err)
      },
    })
  })
}

export function searchRoomsByName(data) {
  return request({
    url: '/api/gptRoom/list',
    data,
  })
}

export function generateImage(data) {
  return request({
    url: '/api/creatImage',
    method: 'POST',
    data,
  })
}

export function getRandomList() {
  return request({
    url: '/api/gptInstructions/randomList',
    method: 'GET',
  })
}

export function getList() {
  return request({
    url: '/api/gptInstructions/list',
    method: 'GET',
  })
}